package com.cloudspace.jindun.update;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;

import com.cloudspace.jindun.JindunApp;
import com.cloudspace.jindun.R;
import com.cloudspace.jindun.activity.MainActivity;
import com.cloudspace.jindun.activity.Woyao.SystemSettingsActivity;
import com.cloudspace.jindun.ext.aq.AQUtility;
import com.cloudspace.jindun.log.APPLog;
import com.cloudspace.jindun.utils.MD5Util;
import com.cloudspace.jindun.utils.MMAlert;
import com.cloudspace.jindun.utils.MyDialog;
import com.cloudspace.jindun.utils.ObjUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

import static android.content.Context.DOWNLOAD_SERVICE;
import static com.cloudspace.jindun.utils.Utility.getSDPath;

public class UpdateAgent {
    public static final int DOWNLOAD_APK_NOTIFY_ID = 12934445;

    private static final String TAG = UpdateAgent.class.getSimpleName();

    private MyDialog mergeProgressDialog;
    private ProgressBar mProgressBar = null;
    private TextView mProgressRate;
    private SystemSettingsActivity mActivity;
    DownloadFileAsync updateJindunApk;
    private File downloadFile;

    private String updateType;

    // 用于测试的packageName
    public static final String TEST_PACKAGENAME = "com.Jindun";

    public static final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");

    public void update(SystemSettingsActivity activity) {
        mActivity = activity;
        AQUtility.postDelayed(new Runnable() {
            @Override
            public void run() {
                showUpdateDialog(mActivity);
            }
        }, 500);
    }

    private UpdateInfo getUpdateinfo(){
        return JindunApp.getInstance().getUpdateInfo();
    }

    private void showUpdateDialog(Activity mActivity) {
        UpdateInfo updateInfo = getUpdateinfo();
        if (ObjUtil.isEmpty(updateInfo)) return;
        String mUpdateInfoStr = updateInfo.getUpdateinfo();
        if (mUpdateInfoStr == null || "".equals(mUpdateInfoStr)) {
            mUpdateInfoStr = mActivity.getString(R.string.update_message);
        }

        updateType = updateInfo.getMustupdate();

        if (updateType.contains("must")) {
            MMAlert.showAlert(mActivity, mUpdateInfoStr, mActivity.getResources().getString(R.string.update_title), mActivity.getResources().getString(R.string.update_now),
                    false, new DialogInterface.OnClickListener() {
                @TargetApi(Build.VERSION_CODES.HONEYCOMB)
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    startDownloadApk();
                    dialogInterface.dismiss();
                }
            });
        } else {
            MMAlert.showAlert(mActivity, mUpdateInfoStr, mActivity.getResources().getString(R.string.update_title), null, mActivity.getResources().getString(R.string.update_now),
                    mActivity.getResources().getString(R.string.update_next_time), false, new DialogInterface.OnClickListener() {
                @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    startDownloadApk();
                }
            }, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            });
        }
    }

    private long downloadId = 0;
    private DownloadManager downloadManager;
    private DownloadChangeObserver downloadObserver;

    private void updateDownloadProgress(int progress){
        APPLog.zxhLog(TAG + " updateDownloadProgress:" + progress);

        if (progress < 0){
            progress = 0;
        }

        if (progress > 100){
            progress = 100;
        }

        final int downloadProgress = progress;

        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mProgressBar != null){
                    mProgressBar.setProgress(downloadProgress);
                    displayDownloadProgress(downloadProgress);
                }
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
    private void startDownloadApk() {
//        if (updateJindunApk == null) {
//            updateJindunApk = new DownloadFileAsync();
//        }
//        if (updateJindunApk.getStatus() != AsyncTask.Status.RUNNING) {
//            updateJindunApk.execute();
//        }

        UpdateInfo updateInfo = getUpdateinfo();
        if (ObjUtil.isEmpty(updateInfo)){
            return;
        }

        DownloadManager.Request request = new DownloadManager.Request(
                Uri.parse(updateInfo.getUpdateurl()));
        request.setDestinationInExternalPublicDir("/.jindun/apk",
                "jindun.apk");
        request.setTitle(JindunApp.getInstance().getString(R.string.update_download));
        request.setDescription(JindunApp.getInstance().getString(R.string.update_download));
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        request.setVisibleInDownloadsUi(false);
        // request.allowScanningByMediaScanner();
        // request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
        // request.setShowRunningNotification(false);
        // request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);

        downloadManager = (DownloadManager) JindunApp.getInstance().getSystemService(DOWNLOAD_SERVICE);
        downloadId = downloadManager.enqueue(request);


        MainActivity.downloadId = downloadId;

        downloadObserver = new DownloadChangeObserver(null);
        JindunApp.getInstance().getContentResolver().registerContentObserver(CONTENT_URI, true, downloadObserver);

        showDownloadProgress(mActivity);
    }

    /* private void cancelDownloadApk(){
         if(updateJindunApk != null){
             updateJindunApk.cancel(true);
         }
     }*/
    public class DownloadFileAsync extends AsyncTask<String, Integer, Boolean> {
        private long totalSize = 0;
        private long curSize = 0;
        public int progress = 0;
        private int retryTime = 3;

        /**
         * 开始执行任务前 ，doinbackgroud前
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDownloadProgress(mActivity);
        }

        @Override
        protected Boolean doInBackground(String... args) {
            if (isCancelled()) return false;

            boolean isSuccess = false;
            do {
                isSuccess = downloadApk();
                if (!isSuccess) {
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {}
                }
            } while (!isSuccess && --retryTime > 0);// 不成功,重试3次
            return isSuccess;
        }

        /**
         * 更新进度信息
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progress = Math.min(values[0], 100);
            if (mergeProgressDialog != null && mergeProgressDialog.isShowing() && progress > 1) {
                mProgressBar.setProgress(progress);
                displayDownloadProgress(progress);
            } else {
                updateDownloadNotification(mActivity, progress);
            }
        }

        /**
         * 成功后调用
         */
        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            dismissDownloadProgress();
            //下载完成后取消进度条并安装
            if (result) {
                installLatestApk(mActivity);
            }
        }

        /**
         * 取消或是异常
         */
        @Override
        protected void onCancelled() {
            super.onCancelled();
            dismissDownloadProgress();
            cancelDownloadNotification(mActivity);
        }

        private Boolean downloadApk() {
            boolean isSuccess = false;
            UpdateInfo updateInfo = getUpdateinfo();
            if (ObjUtil.isEmpty(updateInfo)) return false;

            String updateUrl = updateInfo.getUpdateurl();
            String updateMd5 = updateInfo.getUpdatemd5();

            String downloadFilePath = null;
            String downloadUrl = null;
            String downloadMd5 = null;
            boolean isDownloadSuccess = false;

            if (!TextUtils.isEmpty(updateUrl) && !TextUtils.isEmpty(updateMd5)) {
                downloadFilePath = updateMd5 + ".apk";
                downloadUrl = updateUrl;
                downloadMd5 = updateMd5;
            }

            try {
                downloadFile = getLatestApkFile(downloadFilePath);
                if (Log.isLoggable(TAG, Log.DEBUG)) {
                    Log.d(TAG, "updateUrl : " + updateUrl);
                    Log.d(TAG, "updateMd5 : " + updateMd5);
                }
                RandomAccessFile af = null;
                if (downloadFile == null) {
                    isSuccess = false;
                    return isSuccess;
                } else if (!downloadFile.exists()) {
                    downloadFile.createNewFile();
                } else {
                    String md5 = MD5Util.calculateMD5(downloadFile);
                    if (!TextUtils.isEmpty(md5) && md5.equals(downloadMd5)) {
                        isDownloadSuccess = true;
                        publishProgress(99);
                    } else {
                        curSize = downloadFile.length();
                    }
                }

                if (!isDownloadSuccess) {
                    if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "begin download file :" + downloadFile.getAbsolutePath());
                    }

                    URL url=new URL(updateUrl);
                    HttpURLConnection conn=(HttpURLConnection)url.openConnection();

                    InputStream input=conn.getInputStream();

                    OutputStream output = new FileOutputStream(downloadFile);

                    int ch = 0;
                    int percent = 0;

                    byte[] buffer=new byte[4*1024];
                    while((ch = input.read(buffer)) != -1){
                        curSize += ch;
                        output.write(buffer);

//                        int newPercent = (int) (100.0 * curSize / totalSize);
//                        if (newPercent > percent && newPercent <= 99) {// 还有合并的工作量,下载过程中只显示到99
//                            percent = newPercent;
//                            publishProgress(percent);
//                        }
                    }

                    isSuccess = true;
                    output.flush();

                    input.close();
                    output.close();
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
            return isSuccess;
        }
    }

    public static File getLatestApkFile(String filePath) {
        File sdDir = getSDPath();
        if (sdDir != null && sdDir.isDirectory()) {
            File ktv = new File(sdDir, ".jindun/apk");
            if (ktv.exists()) {
                // 清除老的APK文件
                File[] files = ktv.listFiles();
                for (File f : files) {
                    if (!f.getName()
                            .toLowerCase().contains(filePath)) {
                        f.delete();
                    }
                }
            } else {
                ktv.mkdirs();
            }
            return new File(ktv, filePath);
        }
        return null;
    }

    public void showDownloadProgress(final Activity mActivity) {
        if (mActivity.isFinishing()) {
            return;
        }

        if (null == mergeProgressDialog || !mergeProgressDialog.isShowing()) {
            View mPopView = LayoutInflater.from(mActivity).inflate(R.layout.upload_popup_box, null);
            mProgressBar = (ProgressBar) mPopView.findViewById(R.id.upload_progress);
            mProgressBar.setProgress(0);
            mProgressRate = (TextView) mPopView.findViewById(R.id.progress_text);

            mergeProgressDialog = MMAlert.showAlert(mActivity, mActivity.getString(R.string.update_download), mPopView,
                    null, null);
//            else {
//                mergeProgressDialog = MMAlert.showAlert(mActivity, mActivity.getString(R.string.update_download), mPopView,
//                        mActivity.getString(R.string.update_run_background), new DialogInterface.OnClickListener() {
//                            public void onClick(DialogInterface dialog, int whichButton) {
//                                showDownloadNotification(mActivity);
//                                dialog.dismiss();
//                            }
//                        });
//            }
        }
        mergeProgressDialog.setCancelable(false);
        if (!mergeProgressDialog.isShowing()) {
            mergeProgressDialog.show();
        }
    }


    public void displayDownloadProgress(int rate) {
        if (rate > 0.5 && !mActivity.isFinishing()) {
            try {
                mProgressRate.setText(rate + "%");
                mProgressBar.setProgress(rate);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void dismissDownloadProgress() {
        if (null != mergeProgressDialog && mergeProgressDialog.isShowing()) {
            mergeProgressDialog.dismiss();
            mergeProgressDialog = null;
        }
    }

    NotificationManager nm = null;
    Notification notification = null;
    RemoteViews mRemoteViews;

    //在Navigation中显示出进度条
    private void showDownloadNotification(Activity mContext) {
        nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

        int iconResid = R.drawable.ic_launcher;
        notification = new Notification(iconResid,
                mContext.getString(R.string.downloading_new_version), System.currentTimeMillis());
        mRemoteViews = new RemoteViews(mContext.getPackageName(),
                R.layout.download_notification);

        //使用notification.xml文件作VIEW
        mRemoteViews.setProgressBar(R.id.pb, 100, 0, false);
        mRemoteViews.setTextViewText(R.id.down_tv,
                mContext.getString(R.string.update_progress, 0) + "%");

        notification.contentView = mRemoteViews;
        //设置进度条，最大值 为100,当前值为0，最后一个参数为true时显示条纹
        Intent intent = new Intent(mContext, MainActivity.class);
        notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
        notification.flags |= Notification.FLAG_ONGOING_EVENT;
        nm.notify(DOWNLOAD_APK_NOTIFY_ID, notification);
    }

    //获得新的文件部分时更新进度条
    private void updateDownloadNotification(Activity mContext, int progress) {
        if (nm == null) {
            nm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        }
        if (notification != null) {
            if (mRemoteViews != null) {
                mRemoteViews.setProgressBar(R.id.pb, 100, progress, false);
                mRemoteViews.setTextViewText(R.id.down_tv, mContext.getString(R.string.update_progress, progress) + "%");
                notification.contentView = mRemoteViews;
            }
            //设置进度条，最大值 为100,当前值为0，最后一个参数为true时显示条纹
            Intent intent = new Intent(mContext, MainActivity.class);
            notification.contentIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
            notification.flags |= Notification.FLAG_ONGOING_EVENT;
            nm.notify(DOWNLOAD_APK_NOTIFY_ID, notification);
        }
    }

    //取消通知
    private void cancelDownloadNotification(Activity mActivity) {
        if (nm == null) {
            nm = (NotificationManager) mActivity.getSystemService(Context.NOTIFICATION_SERVICE);
        }
        nm.cancel(DOWNLOAD_APK_NOTIFY_ID);
    }


    private void installLatestApk(Activity mActivity) {
        cancelDownloadNotification(mActivity);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(downloadFile), "application/vnd.android.package-archive");
        mActivity.startActivity(intent);
    }

    public void install(Context context) {
        Intent i = new Intent(Intent.ACTION_VIEW);

        String filePath = getSDPath().getAbsolutePath()+"/.jindun/apk/jindun.apk";

        try{
            i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        }catch (Exception e){
            APPLog.zxhLog(TAG + Log.getStackTraceString(e));
        }

    }

    private void queryDownloadStatus() {
        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(downloadId);
        Cursor c = downloadManager.query(query);
        if(c!=null&&c.moveToFirst()) {
            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));

            int reasonIdx = c.getColumnIndex(DownloadManager.COLUMN_REASON);
            int titleIdx = c.getColumnIndex(DownloadManager.COLUMN_TITLE);
            int fileSizeIdx =
                    c.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES);
            int bytesDLIdx =
                    c.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
            String title = c.getString(titleIdx);
            int fileSize = c.getInt(fileSizeIdx);
            int bytesDL = c.getInt(bytesDLIdx);

            // Translate the pause reason to friendly text.
            int reason = c.getInt(reasonIdx);
            StringBuilder sb = new StringBuilder();
            sb.append(title).append("\n");
            sb.append("Downloaded ").append(bytesDL).append(" / " ).append(fileSize);

            // Display the status
            APPLog.zxhLog(TAG +  sb.toString());
            switch(status) {
                case DownloadManager.STATUS_PAUSED:
                    APPLog.zxhLog(TAG +  "STATUS_PAUSED");
                case DownloadManager.STATUS_PENDING:
                    APPLog.zxhLog(TAG +  "STATUS_PENDING");
                case DownloadManager.STATUS_RUNNING:
                    //正在下载，不做任何事情
                    APPLog.zxhLog(TAG +  "STATUS_RUNNING");
                    updateDownloadProgress((int) (bytesDL*100.0) / fileSize);
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    //完成
                    APPLog.zxhLog(TAG +  "下载完成");
                    updateDownloadProgress(100);

                    if(mergeProgressDialog != null){
                        mergeProgressDialog.dismiss();
                        mergeProgressDialog = null;
                    }

                    install(mActivity);
                    break;
                case DownloadManager.STATUS_FAILED:
                    //清除已下载的内容，重新下载
                    APPLog.zxhLog(TAG +  "STATUS_FAILED");
                    downloadManager.remove(downloadId);
                    break;
            }
        }
    }

    class DownloadChangeObserver extends ContentObserver {
        public DownloadChangeObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            queryDownloadStatus();
        }
    }
}
